<?php
/**
 *
 *
 */
abstract class Yz_Module_WebModule
    extends Yz_Module_Abstract
    implements Yz_Module_Interface, Yz_Module_WebModule_Interface
{

    const DEFAULT_CONTROLLER = "default";


    /**
     *  @return string|bool(false)
     */
    public function hasController($controllerName)
    {
        debug($controllerName);
        try {
            $class = $this->resolveLibrary( 'Controller', $controllerName );
        } catch (Yz_Exception $ex) {
            return false;
        }
        if ( false === $class ) {
            return false;
        }
        assert('is_subclass_of($class,"Yz_Controller_Interface")');
        return $class;
    }

    /**
     *  @return Yz_Controller_Interface&
     *  new:
     *  @throws LibraryNotFound
     */
    public function selectController($controllerName)
    {
        debug($controllerName);
        $class = $this->hasController($controllerName);
        if (false !== $class) {
            $cntlr = new $class($this);
        } else {
            $cntlr = null;
        }
        return $cntlr;
    }



    /** Select a default controller (usually, when a named controller not found)
     *      It may be an error controller ("controller $name not found")
     *      or module contents generator
     *      or a dispatcher
     *  @return Yz_Controller_Interface&
     * @todo if DEFAULT_CONTROLLER is false, do not resolve it and instantly throw
     *  @throws LibraryNotFound
     */
    public function selectDefaultController()
    {
        $default = static::DEFAULT_CONTROLLER;
        if (! $default) {
            throw new Yz_Exception_NotImplemented();
        }
        $cntlr = $this->selectController($default);
        if (null === $cntlr) {
            // TODO error 404
            $ex = new Yz_Module_Exception_ClassNotFound();
            throw $ex->withArgs(array(
                'moduleName' => $this->name,
                'className' => 'Controller_' . $default,
                ))
                ;
        }
        return $cntlr;
    }


    /** get the list of all controllers defined in the module
     *  the method relies on the assumption that controller classes are not redefined in
     *  the namespaced constants
     *  @return array
     */
    public function getControllersList()
    {
        debug();
        $list = array();
        $ns = $this::namespaceName();
        while ('' !== $ns) {
            $path = strtr($ns, '\\', '/') . '/';
            $files = glob($path . '/Controller/*.php');
            if ($files) {
                foreach ($files as $file) {
                    $ctlName = substr($file, strrpos($file, '/')+1, -4);
                    $list[] = $ctlName;
                }
            }
            $ns = constant($ns . '\\PARENT_NAMESPACE');
        }
        return array_unique($list);
    }

} // class
